package com.gitee.wsl.logger

import kotlinx.cinterop.ExperimentalForeignApi
import platform.posix.*

actual val platformLogPainter: LogPrinter
    get() = NativeLogger("KotlinNative")

@OptIn(ExperimentalForeignApi::class)
class NativeLogger(private val name: String) : LogPrinter {
    private fun stdout(message: String) {
        fprintf(stdout, "[$name] $message\n")
        fflush(stdout)
    }

    private fun stderr(message: String) {
        fprintf(stderr, "[$name] $message\n")
        fflush(stderr)
    }

     fun debug(message: String) = stdout("DEBUG: $message")
     fun debug(message: String, error: Throwable) {
        debug(message)
        debug(error.stackTraceToString())
    }
     fun info(message: String) = stdout("INFO: $message")
     fun info(message: String, error: Throwable) {
        info(message)
        info(error.stackTraceToString())
    }
     fun warn(message: String) = stderr("WARN: $message")
     fun warn(message: String, error: Throwable) {
        warn(message)
        warn(error.stackTraceToString())
    }
     fun error(message: String) = stderr("ERROR: $message")
     fun error(message: String, error: Throwable?) {
        error(message)
         error?.stackTraceToString()?.let { error(it) }
    }
     fun trace(message: String) = stdout("TRACE: $message")
     fun trace(message: String, error: Throwable?) {
        trace(message)
        error?.stackTraceToString()?.let { trace(it) }
    }

    override fun log(
        level: LogLevel,
        tag: String,
        messageAny: Any?,
        throwable: Throwable?,
    ) {
        when(level){
            LogLevel.VERBOSE -> stdout(messageAny.toString())
            LogLevel.DEBUG -> debug(messageAny.toString())
            LogLevel.INFO -> info(messageAny.toString())
            LogLevel.WARNING -> warn(messageAny.toString())
            LogLevel.ERROR -> error(messageAny.toString(), throwable)
            LogLevel.WTF -> trace(messageAny.toString(), throwable)
        }
    }
}